<!--
 * @Author: fisher
 * @Date: 2022-10-24 09:36:55
 * @LastEditTime: 2022-10-26 17:14:26
 * @LastEditors: fisher
 * @Description: 
 * @FilePath: \tauri_app\src\views\home\csv.vue
-->
<template>
  <div>
    <div class="area">
      <div class="area_item">
        <span>上传附件</span>
        <input type="file" @change="uploadFile" />
      </div>
      <div class="area_item">
        <span><b>*</b> 指定x字段</span>
        <el-select
          v-model="xField"
          class="m-2"
          placeholder="请指定x字段标题"
          size="large"
        >
          <el-option
            v-for="item in headOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <!-- <el-input v-model="xField" placeholder="请输入x字段标题，默认为x" /> -->
      </div>
      <div class="area_item">
        <span><b>*</b> 指定y字段</span>
        <el-select
          v-model="yField"
          class="m-2"
          placeholder="请指定y字段标题"
          size="large"
        >
          <el-option
            v-for="item in headOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <!-- <el-input v-model="yField" placeholder="请输入y字段标题，默认为y" /> -->
      </div>
      <div class="area_item">
        <span><b>*</b> 指定当前坐标系</span>
        <el-select
          v-model="axisInput"
          class="m-2"
          placeholder="请选择坐标系"
          size="large"
        >
          <el-option
            v-for="item in axisOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </div>
      <div class="area_item">
        <span><b>*</b> 指定输出坐标系</span>
        <el-select
          v-model="axisOutput"
          class="m-2"
          placeholder="请选择坐标系"
          size="large"
        >
          <el-option
            v-for="item in axisOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </div>
      <div class="area_item">
        <span>文件名</span>
        <el-input
          v-model="filename"
          placeholder="请输入文件名，默认为download"
        />
      </div>
      <el-button type="success" round @click="downloadFile">Download</el-button>
    </div>
  </div>
</template>
  
  <script setup>
import { reactive, ref } from "vue";
import Papa from "papaparse";
import GeoTransform from "geotransform";
let gt = new GeoTransform();
const csvData = reactive([]);
let headOptions = reactive([]);
let axisInput = ref("");
let axisOutput = ref("");
let filename = ref("");
let xField = ref("");
let yField = ref("");
const loadingInstance = reactive({});
const axisOptions = [
  {
    value: "GCJ02",
    label: "高德坐标",
  },
  {
    value: "BD09",
    label: "百度坐标",
  },
  {
    value: "BD09MC",
    label: "百度墨卡托坐标",
  },
  {
    value: "EPSG3857",
    label: "墨卡托坐标",
  },
  {
    value: "WGS84",
    label: "WGS84",
  },
  {
    value: "EPSG:4547",
    label: "EPSG:4547",
  },
  {
    value: "EPSG:4490",
    label: "EPSG:4490",
  },
];
const uploadFile = (e) => {
  const fileObj = e.target.files[0];
  analysisCsv(fileObj);
};
const analysisCsv = (obj) => {
  let fReader = new FileReader();
  fReader.readAsDataURL(obj);
  fReader.onload = (evt) => {
    // 将csv转换成二维数组
    Papa.parse(obj, {
      encoding: "gb2312",
      complete: (res) => {
        // UTF8 \r\n与\n混用时有可能会出问题
        csvData.value = res.data;
        if (csvData.value[csvData.value.length - 1] == "") {
          //去除最后的空行
          csvData.value.pop();
        }
        // 提取首行标题，作为指定字段选项
        // 先清空上次提取的标题
        headOptions.length = 0;
        csvData.value[0].forEach((item, index) => {
          headOptions.push({
            value: index,
            label: item,
          });
        });
      },
    });
  };
};

const handleTransform = () => {
  // 获取元数据
  const rowData = [...csvData.value];
  //   在新容器里填充数据
  for (let i = 1, len = rowData.length; i < len; i++) {
    let coordsX = parseFloat(rowData[i][xField.value]);
    let coordsY = parseFloat(rowData[i][yField.value]);
    if (isFinite(coordsX) && isFinite(coordsY)) {
      const result = gt.transform(axisInput.value, axisOutput.value, [
        coordsX,
        coordsY,
      ]);
      rowData[i][xField.value] = result[0];
      rowData[i][yField.value] = result[1];
    } else {
      ElNotification({
        title: "Warning",
        message: `数据导出过程中第${
          i + 1
        }行数据有问题！请检查数据源或直接在导出文件中单独修改`,
        type: "warning",
        position: "top-left",
        duration: 0,
      });
    }
  }
  return rowData;
};

const downloadFile = () => {
  // 判断必选项
  if (
    xField.value == "" ||
    yField.value == "" ||
    axisInput.value == "" ||
    axisOutput.value == ""
  ) {
    ElNotification({
      title: "Warning",
      message: "请补充完整*内容",
      type: "warning",
      position: "top-left",
      duration: 3000,
    });
    return false;
  }
  // 开启loading
  loadingInstance.value = ElLoading.service({
    fullscreen: true,
    text: "处理数据中。。。",
    background: "rgba(0, 0, 0, 0.7)",
    lock: true,
  });
  const res = handleTransform();
  if (!res) {
    resetForm();
    return false;
  }
  const csv = Papa.unparse(res);
  //定义文件内容，类型必须为Blob 否则createObjectURL会报错
  let content = new Blob(["\uFEFF" + csv]);
  //生成url对象
  let urlObject = window.URL || window.webkitURL || window;
  let url = urlObject.createObjectURL(content);
  //生成<a></a>DOM元素
  let el = document.createElement("a");
  //链接赋值
  el.href = url;
  if (filename.value === "") {
    filename.value = "download";
  }
  el.download = `${filename.value}.csv`;
  //必须点击否则不会下载
  el.click();
  //移除链接释放资源
  urlObject.revokeObjectURL(url);
  resetForm();
};
// 重置表单
const resetForm = () => {
  // 清空表单数据
  xField.value = "";
  yField.value = "";
  axisInput.value = "";
  axisOutput.value = "";
  filename.value = "";
  // 结束loading
  loadingInstance.value.close();
};
</script>
  <style  scoped>
.area {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 25px;
}
.area_item {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 20px;
}
.area_item > span {
  width: 200px;
  flex-shrink: 0;
}
b {
  color: red;
}
</style>